﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Pseudogenerator.Common.Generators;

namespace Pseudogenerator.Common.ViewModels
{
    public class CuadraticCongruentialViewModel
        : CongruentialViewModel<CuadraticCongruential>
    {

        public CuadraticCongruentialViewModel()
        {
            this.ModeloActual = new CuadraticCongruential();
        }

        #region ModelFields

        public uint d
        {
            get
            {
                return ModeloActual.d;
            }
            set
            {
                if (ModeloActual.d == value)
                    return;
                ModeloActual.d = value;
                OnPropertyChanged();
                RefreshGUI();
            }
        }

        public uint c
        {
            get
            {
                return ModeloActual.c;
            }
            set
            {
                if (ModeloActual.c == value)
                    return;
                ModeloActual.c = value;
                OnPropertyChanged();
                RefreshGUI();
            }
        }

        #endregion

        public override string Title
        {
            get { return "Congruencial cuadratico"; }
        }

        public override bool CanRun
        {
            get
            {
                return base.CanRun 
                    && ModeloActual.CanGenerateNext;
            }
        }

        protected override void AddPreload()
        {
            var actual = Preloads.FirstOrDefault(i => i.a == a && i.x0 == x0 && i.m == m && i.c == c && i.m == m);
            if (actual == null)
            {
                Preloads.Add(new CuadraticCongruential() { a = a, x0 = x0, m = m, c=c, d=d });
            }
        }

        public override IEnumerable<string> Errors
        {
            get
            {
                if (ModeloActual.a <= 0 ||
                    ModeloActual.c <= 0 ||
                    ModeloActual.d <= 0)
                    yield return "Los parametros deben ser mayor que 0";
                if (ModeloActual.m <= ModeloActual.x0 ||
                    ModeloActual.m <= ModeloActual.a ||
                    ModeloActual.m <= ModeloActual.c ||
                    ModeloActual.m <= ModeloActual.d)
                    yield return "El Modulo ('m') debe ser mayor que los demas parametros";
            }
        }

        public override IEnumerable<string> Recommendations
        {
            get
            {
                if (SonPrimosRelativos(ModeloActual.c, ModeloActual.m))
                    yield return "Se recomienda que 'c' sea relativamente primo a m.";

                if (!MultiplosDePrimosImparesDe(ModeloActual.d, ModeloActual.m))
                    yield return "Se recomienda que 'd' sea multiplo de todos los factores primos impares de 'm'.";

                if (!SonPrimosRelativos((int)ModeloActual.a - 1, ModeloActual.m))
                    yield return "Se recomienda que 'a-1' sea multiplo de todos los factores primos impares de 'm'.";
            }
        }

        private CuadraticCongruential _ModeloActual = null;
        public override CuadraticCongruential ModeloActual
        {
            get
            {
                if (_ModeloActual == null)
                    _ModeloActual = new CuadraticCongruential();

                return _ModeloActual;
            }
            set
            {
                if (value == null) 
                    return;
                this.a = value.a;
                this.x0 = value.x0;
                this.m = value.m;
                this.d = value.d;
                this.c = value.c;
                ClearCommand.Execute(null);
            }
        }


    }
}
